关于包管理器你应该知道的

本文整理自GitChat居玉皓的达人课《Webpack 前端工程化入门》
JavaScript 是一个缺乏标准库的语言。当你想解决 URL 处理、日期处理这类很常见的问题,在没有标准库的情况下就只能自己动手写代码或者从自己以前的工程中拷贝代码。而使用 npm 等包管理器最大的好处是里面有很多非常成熟的包来解决这类问题,可以直接安装到项目中使用,给开发工作带来了很大的便利。

万能修复大法?rm -rf node_modules && npm i

很多开发同学在使用 npm 的时候一发现 npm 模块有问题就执行 rm -rf node_modules && npm i,一些情况下可以解决问题,一些情况下却不能,让我们尝试去看看这是为什么。当我们执行 npm install 或者 yarn 来安装模块的时候,大概经历了几个过程:

  1. 首先会寻找包版本信息文件( pakcage-lock.json,yarn.lock 等),如果发现有版本信息文件,则依照它来进行模块安装。
  2. 检查 pakcage.json 中的依赖,如果此时项目中不存在版本信息文件,则完全按照 pakcage.json 进行安装,并生成一个版本信息文件。如果此时存在版本信息文件,则只会安装 package.json 中有而版本信息文件中没有的包
  3. 如果确实有这种新包,则更新版本信息文件。因此当我们发现项目中的某个包和我们预想不一致时,首先查看版本信息文件中该包的来源和版本,因为在安装过程中它的优先级最高。有的时候执行了 rm -rf node_modules && npm i 也没有解决问题,可能是由于版本信息文件中这个包本身就有问题,无论你怎么删掉重装也还是一样。

不知道包怎么来的?试试 yarn why

1
2
3
4
5
6
7
8
9
10
11
12
13
14
➜  CubeManage git:(master) ✗ yarn why lodash
yarn why v1.5.1
[1/4] 🤔 Why do we have the module "lodash"...?
[2/4] 🚚 Initialising dependency graph...
[3/4] 🔍 Finding dependency...
[4/4] 🚡 Calculating file sizes...
=> Found "lodash@4.17.5"
info Has been hoisted to "lodash"
info Reasons this module exists
- Specified in "dependencies"
- Hoisted from "eslint#lodash"
- Hoisted from "karma-webpack#lodash"
- Hoisted from "karma-phantomjs-launcher#lodash"
- Hoisted from "async#lodash"

搭建内网 npm 仓库

在日常开发中,很多公司内部的包我们不希望发布到 npm 官方仓库,因为里面可能涉及一些不希望暴露给外部的代码。这时我们可以选择在公司内网搭建 npm 私有仓库。借助 npm 的 scope 特性我们可以实现公有和私有包的区分,在为 npm 包设定名字的时候可以加上 scope它的格式是 @somescope/somepackagename,比如公司内部的包命名可以为 @mynpm/myui,这种包只能上传到私有仓库,官方仓库是不接受的。现在比较主流的解决方案有 cnpmverdaccio。两者的区别主要在于同步官方仓库包的机制:

  • cnpm 的机制把所有官方仓库的包拷贝到私有仓库中,然后每隔几分钟从官方仓库中同步一次。这样的优点是用户下载包会比较快,缺点是包刚发布上去可能需要等待几分钟来同步或者去手动同步。另外就是对硬盘要有一定要求,毕竟全球那么多 JavaScript 开发者每天都在发布无数的包上去,都需要去同步到内网仓库中。
  • verdaccio 相对来说则智能一些。它并不会主动拷贝和同步官方源的包,只有在用户去安装包的时候才从官方的仓库拉取,并在本地生成缓存。经过验证在一段时间之后它的缓存命中率是非常高的,因为用户在绝大多数情况下都在安装同样的包。以上通过区分内外网仓库,可以防止内部的包泄露到外网中。